package org.linlinjava.litemall.wx.service;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.paypal.api.payments.*;
import com.paypal.base.rest.APIContext;
import com.paypal.base.rest.PayPalRESTException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.linlinjava.litemall.core.notify.AwsNotifyService;
import org.linlinjava.litemall.core.notify.NoticeHelper;
import org.linlinjava.litemall.core.payment.DefaultCurType;
import org.linlinjava.litemall.core.payment.PaymentResponseCode;
import org.linlinjava.litemall.core.payment.paypal.config.PaypalPaymentIntent;
import org.linlinjava.litemall.core.payment.paypal.config.PaypalPaymentMethod;
import org.linlinjava.litemall.core.payment.paypal.config.PaypalPaymentState;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.beans.Constants;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.wx.constant.LitemallWXConstants;
import org.linlinjava.litemall.wx.dto.SubscribeConfirmDTO;
import org.linlinjava.litemall.wx.dto.SubscribePayAfterSuccessDTO;
import org.linlinjava.litemall.wx.manage.WxNewSubscribeManageService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

import static org.linlinjava.litemall.wx.util.WxResponseCode.MOBILE_CODE_ONE;
import static org.linlinjava.litemall.wx.util.WxResponseCode.TAX_NOT_EXIST;

/**
 * wx新订阅服务
 *
 * @author yliyun
 * @date 2022/10/20
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class WxNewSubscribeService {

    /**
     * 支付成功 （给自己购买时回调的URL）
     */
    @Value("${subscribe.paypal.suceess}")
    private static String paySuccess;

    /**
     * 支付取消 （给自己购买时回调的URL）
     */
    @Value("${subscribe.paypal.cancel}")
    private static String payCancel;

    /**
     * 支付成功 （给别人赠送时回调的URL）
     */
    @Value("${subscribe.paypal2.suceess}")
    private static String payGiveeSuccess;


    @Autowired
    private APIContext apiContext;

    /**
     * litemall用户服务
     */
    @Autowired
    private LitemallUserService litemallUserService;
    /**
     * 订单服务
     */
    @Autowired
    private LitemallOrderService litemallOrderService;

    /**
     * 卢米埃订阅规则服务
     */
    @Autowired
    private LumiereSubscribeRuleService lumiereSubscribeRuleService;

    @Autowired
    private LumiereSubscribeService lumiereSubscribeService;

    @Autowired
    private LumiereSubscribeUserOrderService lumiereSubscribeUserOrderService;

    @Autowired
    private LitemallGoodsProductService litemallGoodsProductService;

    @Autowired
    private LitemallGoodsService litemallGoodsService;

    @Autowired
    private LitemallTaxService litemallTaxService;

    /**
     * 地区服务
     */
    @Autowired
    private LitemallRegionService regionService;

    @Autowired
    private NoticeHelper noticeHelper;

    @Autowired
    private AwsNotifyService awsNotifyService;

    /**
     * 商品地区服务
     */
    @Autowired
    private LitemallGoodsRegionService goodsRegionService;

    @Autowired
    private LitemallShopRegionService litemallShopRegionService;

    @Autowired
    private LumiereSubscribeUserService lumiereSubscribeUserService;

    @Autowired
    private LumiereSubscribeUserLogService lumiereSubscribeUserLogService;

    @Autowired
    private LumiereSubscribeOrderService lumiereSubscribeOrderService;

    @Autowired
    private WxNewSubscribeManageService wxNewSubscribeManageService;


    /**
     * 创建订阅预支付订单
     *
     * @return {@link ResponseUtil.Response}
     * @param userId
     * @param subscribePayAfterSuccessDto
     */
    @Transactional
    public ResponseUtil.Response advancePaymentOrder(Integer userId, SubscribePayAfterSuccessDTO subscribePayAfterSuccessDto) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }
        LitemallUser user = litemallUserService.findById(userId);
        if(ObjectUtil.isEmpty(user)){
            return ResponseUtil.fail("用户不存在");
        }
        //通过ruleId查询订阅方式
        LumiereSubscribeRule rule = lumiereSubscribeRuleService.queryByPrimaryKey(subscribePayAfterSuccessDto.getRuleId());
        if (rule == null) {
            return ResponseUtil.fail(222, "订阅方式不正确");
        }
        //创建订阅预支付订单
        LumiereSubscribeOrder subscribeOrder = LumiereSubscribeOrder.builder()
                .deliveryMethod(subscribePayAfterSuccessDto.getTransportType())
                .addUserId(userId)
                .addUserName(user.getUsername())
                .build();

        //如果是创建赠送的订单
        if (StrUtil.isNotBlank(subscribePayAfterSuccessDto.getGivee())){
            LitemallUser giveeUser = litemallUserService.queryMobileOrEmail(subscribePayAfterSuccessDto.getGivee());
            subscribeOrder.setAddUserId(ObjectUtil.isNotEmpty(giveeUser)?giveeUser.getId():null);
            subscribeOrder.setAddUserName(subscribePayAfterSuccessDto.getGivee());
        }

        BeanUtils.copyProperties(subscribePayAfterSuccessDto,subscribeOrder);
        lumiereSubscribeOrderService.save(subscribeOrder);

        Map map= new HashMap();
        map.put("userId",userId);
        map.put("subscribeOrderId",subscribeOrder.getId());
        return ResponseUtil.ok(map);
    }

    /**
     * paypal准备支付 （给自己购买）
     *
     * @param userId           用户id
     * @param subscribeOrderId 订阅订单id
     * @return {@link Object}
     */
    public Object payAfterSuccess(Integer userId, Long subscribeOrderId) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }
        //回调RUL
        String sUrl = paySuccess+"?subscribeOrderId="+subscribeOrderId;
        LumiereSubscribeOrder subscribeOrder = lumiereSubscribeOrderService.getById(subscribeOrderId);
        if(ObjectUtil.isEmpty(subscribeOrder)){
            return ResponseUtil.fail(PaymentResponseCode.ORDER_UNKNOWN, "订单不存在");
        }
        //预订单的里面预设值为null
        if(subscribeOrder.getPayStatus() != 1){
            return ResponseUtil.fail(PaymentResponseCode.ORDER_INVALID_OPERATION, "订单不能支付");//OrderUtil.STATUS_CREATE
        }
        Amount amount = new Amount();
        amount.setCurrency(DefaultCurType.CAD.getType());
        amount.setTotal(String.format("%.2f", subscribeOrder.getPrice()));

        Transaction transaction = new Transaction();
        transaction.setDescription("lumiere subscribe pay");
        transaction.setAmount(amount);

        List<Transaction> transactions = new ArrayList<>();
        transactions.add(transaction);

        Payer payer = new Payer();
        payer.setPaymentMethod(PaypalPaymentMethod.paypal.toString());

        Payment payment = new Payment();
        payment.setIntent(PaypalPaymentIntent.sale.toString());
        payment.setPayer(payer);
        payment.setTransactions(transactions);
        RedirectUrls redirectUrls = new RedirectUrls();
        redirectUrls.setCancelUrl(payCancel);
        redirectUrls.setReturnUrl(sUrl);
        payment.setRedirectUrls(redirectUrls);

        try {
            log.debug("success url is " + redirectUrls.getReturnUrl());
            log.debug("cancel url is " + redirectUrls.getCancelUrl());
            log.debug("进入支付之前的日志");
            Payment rtn =  payment.create(apiContext);
            log.debug("进入支付页面之后的日志");
            if(null == rtn.getId() || !PaypalPaymentState.created.toString().equals(rtn.getState())){
                return ResponseUtil.fail(PaymentResponseCode.ORDER_INVALID_OPERATION, "订单不能支付");
            }
            String paymentId = rtn.getId();
            //保存paymentId作为PayPal的商户订单号
            subscribeOrder.setOutTradeNo(paymentId);
            lumiereSubscribeOrderService.updateById(subscribeOrder);
            return rtn;
        } catch (PayPalRESTException e) {
            e.printStackTrace();
            return ResponseUtil.fail(PaymentResponseCode.ORDER_INVALID_OPERATION, "订单不能支付");
        }
    }

    /**
     * paypal准备支付 （赠送）
     *
     * @param userId          用户id
     * @param subscribeOrderId 订阅订单id
     * @return {@link Object}
     */
    public Object payGiveeAfterSuccess(Integer userId,Long subscribeOrderId,String message) {
        if (userId == null) {
            return ResponseUtil.unlogin();
        }
        //回调RUL
        String sUrl = payGiveeSuccess+"?subscribeOrderId="+subscribeOrderId+"&message="+message;
        LumiereSubscribeOrder subscribeOrder = lumiereSubscribeOrderService.getById(subscribeOrderId);
        if(ObjectUtil.isEmpty(subscribeOrder)){
            return ResponseUtil.fail(PaymentResponseCode.ORDER_UNKNOWN, "订单不存在");
        }
        //预订单的里面预设值为null
        if(subscribeOrder.getPayStatus() != 1){
            return ResponseUtil.fail(PaymentResponseCode.ORDER_INVALID_OPERATION, "订单不能支付");//OrderUtil.STATUS_CREATE
        }
        Amount amount = new Amount();
        amount.setCurrency(DefaultCurType.CAD.getType());
        amount.setTotal(String.format("%.2f", subscribeOrder.getPrice()));

        Transaction transaction = new Transaction();
        transaction.setDescription("lumiere subscribe pay");
        transaction.setAmount(amount);

        List<Transaction> transactions = new ArrayList<>();
        transactions.add(transaction);

        Payer payer = new Payer();
        payer.setPaymentMethod(PaypalPaymentMethod.paypal.toString());

        Payment payment = new Payment();
        payment.setIntent(PaypalPaymentIntent.sale.toString());
        payment.setPayer(payer);
        payment.setTransactions(transactions);
        RedirectUrls redirectUrls = new RedirectUrls();
        redirectUrls.setCancelUrl(payCancel);
        redirectUrls.setReturnUrl(sUrl);
        payment.setRedirectUrls(redirectUrls);

        try {
            log.debug("success url is " + redirectUrls.getReturnUrl());
            log.debug("cancel url is " + redirectUrls.getCancelUrl());
            log.debug("进入支付之前的日志");
            Payment rtn =  payment.create(apiContext);
            log.debug("进入支付页面之后的日志");
            if(null == rtn.getId() || !PaypalPaymentState.created.toString().equals(rtn.getState())){
                return ResponseUtil.fail(PaymentResponseCode.ORDER_INVALID_OPERATION, "订单不能支付");
            }
            String paymentId = rtn.getId();
            //保存paymentId作为PayPal的商户订单号
            subscribeOrder.setOutTradeNo(paymentId);
            lumiereSubscribeOrderService.updateById(subscribeOrder);
            return rtn;
        } catch (PayPalRESTException e) {
            e.printStackTrace();
            return ResponseUtil.fail(PaymentResponseCode.ORDER_INVALID_OPERATION, "订单不能支付");
        }
    }


    /**
     * 执行付款
     *
     * @param paymentId 支付id
     * @param payerId   付款人身份
     * @return {@link Object}
     */
    public Object executePayment(String paymentId, String payerId){
        log.debug("paypal success");
        log.debug("更新订单信息之前");
        //根据商户订单号（paypal:paymentId）拿到订单
        LumiereSubscribeOrder order = lumiereSubscribeOrderService.getOne(Wrappers.lambdaQuery(LumiereSubscribeOrder.class)
                        .eq(LumiereSubscribeOrder::getOutTradeNo,paymentId));
        try {
            Payment payment = new Payment();
            payment.setId(paymentId);
            PaymentExecution paymentExecute = new PaymentExecution();
            paymentExecute.setPayerId(payerId);
            Payment rtn = payment.execute(apiContext, paymentExecute);
            // 交易号
            String transationId = rtn.getTransactions().get(0).getRelatedResources().get(0).getSale().getId();
            if(rtn.getState().equals("approved")){
                List<Transaction> transactions = rtn.getTransactions();
                BigDecimal totalFee = new BigDecimal(0.00);
                if(transactions != null){
                    for(Transaction transaction: transactions){
                        String total = transaction.getAmount().getTotal();
                        BigDecimal b = new BigDecimal(total);
                        b.setScale(2, BigDecimal.ROUND_DOWN);
                        totalFee = totalFee.add(b);
                    }
                }
                if (order == null) {
                    return ResponseUtil.fail(PaymentResponseCode.ORDER_UNKNOWN, "订单不存在");
                }

                // 检查这个订单是否已经处理过
                if (order.getPayStatus() != 1) {
                    return ResponseUtil.fail(PaymentResponseCode.PAYMENT_FAIL, "订单已经处理成功!");
                }

                // 检查支付订单金额
                if (!totalFee.toString().equals(order.getPrice().toString())) {
                    return ResponseUtil.fail(PaymentResponseCode.PAYMENT_FAIL, " : 支付金额不符合 totalFee=" + totalFee);
                }
                order.setPayType(Constants.PAY_TYPE_PAYPAL);
                order.setCurrency(DefaultCurType.CAD.getType());
                order.setTransationId(transationId);        //交易号，退款时需要用到
                order.setPayId(payment.getId());            //付款编号，获取详情是需要用到？
                order.setPayTime(LocalDateTime.now());
                log.debug("更新订单信息");
                if (!lumiereSubscribeOrderService.updateById(order)) {
                    return ResponseUtil.updatedDateExpired();
                }
                return rtn;
            }else{
                log.info("gift subscribe executePayment error : "+ rtn.toJSON());
                return ResponseUtil.fail(PaymentResponseCode.PAYMENT_FAIL, "支付失败");
            }
        }catch (Exception e){
            //支付异常，退款
            RefundRequest refund = new RefundRequest();
            Amount amount = new Amount();
            amount.setCurrency(order.getCurrency());
            amount.setTotal(String.format("%.2f", order.getPrice()));
            refund.setAmount(amount);
//        refund.setReason(order.getDescription());
            try {
                if(StringUtils.isEmpty(order.getTransationId())) {
                    //注意这段代码，获取saleId
                    Payment payment = Payment.get(apiContext, order.getPayId());
                    Transaction transaction = payment.getTransactions().get(0);
                    RelatedResources resources = transaction.getRelatedResources().get(0);
                    String id = resources.getSale().getId();
                    order.setTransationId(id);
                }
                Sale sale = new Sale();
                sale.setId(order.getTransationId());
                DetailedRefund res = sale.refund(apiContext, refund);
                if(res.getState().equals(PaypalPaymentState.completed.toString())){
                    return true;
                }
                return false;
            } catch (PayPalRESTException p) {
                p.printStackTrace();
                return false;
            }
        }
    }

    /**
     * 创建或更新卡片
     * @param subscribeOrderId
     */
    @Transactional
    public ResponseUtil.Response createOrUpdate(Long subscribeOrderId) {
        //更改支付状态
        LumiereSubscribeOrder subscribeOrder = lumiereSubscribeOrderService.getById(subscribeOrderId);
        if(ObjectUtil.isEmpty(subscribeOrder)){
            return ResponseUtil.fail(PaymentResponseCode.ORDER_UNKNOWN, "订单不存在");
        }
        subscribeOrder.setPayStatus(2);
        lumiereSubscribeOrderService.updateById(subscribeOrder);
        //创建订阅用户
        LumiereSubscribeUser subscribeUser = new LumiereSubscribeUser();
        //通过ruleId查询订阅方式
        LumiereSubscribeRule rule = lumiereSubscribeRuleService.queryByPrimaryKey(subscribeOrder.getRuleId());
        subscribeUser.setSubscribeId(rule != null ? rule.getSubscribeId() : null);
        subscribeUser.setShopId(subscribeOrder.getShopId());
        subscribeUser.setGoodsId(subscribeOrder.getGoodsId());
        //设置goods_product_id
        subscribeUser.setGoodsProductId(queryGoodsProductId(subscribeOrder.getShopId(), subscribeOrder.getGoodsId()));
        subscribeUser.setNumber(subscribeOrder.getNumber());
        subscribeUser.setPrice(subscribeOrder.getPrice() != null ? subscribeOrder.getPrice() : rule.getPrice());
        subscribeUser.setAutoPayType((byte) 3);
        subscribeUser.setMethod(rule != null ? rule.getRuleType() : null);
        subscribeUser.setRuleId(subscribeOrder.getRuleId());

        subscribeUser.setDeliveryMethod(subscribeOrder.getDeliveryMethod() != null ? subscribeOrder.getDeliveryMethod() : null);
        //计算startTime和endTime
        LocalDateTime startTime = LocalDateTime.now();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar cal = Calendar.getInstance();
        Date startDate = Date.from( startTime.atZone( ZoneId.systemDefault()).toInstant());
        cal.setTime(startDate);
        String end;
        LocalDateTime endTime = null;
        switch (rule.getRuleType()) {
            case 1:
                cal.add(Calendar.DATE, +7);
                end = sdf.format(cal.getTime());
                endTime = LocalDateTime.parse(end, df);
                break;

            case 2:
                cal.add(Calendar.MONTH, +1);
                end = sdf.format(cal.getTime());
                endTime = LocalDateTime.parse(end, df);
                break;

            default:
                cal.add(Calendar.YEAR, +1);
                end = sdf.format(cal.getTime());
                endTime = LocalDateTime.parse(end, df);
                break;
        }
        subscribeUser.setStartTime(startTime);
        subscribeUser.setEndTime(endTime);
        Object taxPrice = this.getTaxPrice(subscribeOrder);
        if (taxPrice instanceof ResponseUtil.Response) {
            ResponseUtil.Response resp = (ResponseUtil.Response) taxPrice;
            return ResponseUtil.fail(resp.getErrno(), resp.getErrmsg());
        } else {
            subscribeUser.setTaxPrice((BigDecimal) taxPrice);
        }

        if (subscribeOrder.getDeliveryStartTime() != null) {
            subscribeUser.setDeliveryStartTime(subscribeOrder.getDeliveryStartTime());
        }

        if (subscribeOrder.getDeliveryEndTime() != null) {
            subscribeUser.setDeliveryEndTime(subscribeOrder.getDeliveryEndTime());
        }

        //插入subscribeUser表
        subscribeUser.setUserId(subscribeOrder.getUserId());
        LitemallUser user = litemallUserService.findById(subscribeOrder.getUserId());
        subscribeUser.setUserName(user.getUsername());
        subscribeUser.setAddTime(LocalDateTime.now());
        subscribeUser.setUpdateTime(LocalDateTime.now());
        lumiereSubscribeUserService.add(subscribeUser);
        //创建订单
        LitemallOrder order = new LitemallOrder();
        order.setUserId(subscribeOrder.getUserId());
        order.setShopId(subscribeOrder.getShopId());
        order.setOrderSn(RandomUtil.randomNumbers(16));
        order.setSerialNo(litemallOrderService.getTodayMaxSerialNo(subscribeOrder.getShopId()));
        order.setOrderStatus(Constants.ORDER_STATUS_ONGOING);
        order.setOrderPrice(subscribeOrder.getPrice());
        order.setEvaluationStatus((byte)0);
        order.setMessage(subscribeOrder.getMessage());
        order.setGoodsPrice(order.getGoodsPrice());
        order.setPayType(Constants.PAY_TYPE_PAYPAL);
        order.setOrderSource((byte) 1);
        litemallOrderService.add(order);

        //创建订阅订单
        LumiereSubscribeUserOrder subscribeUserOrder = new LumiereSubscribeUserOrder();
        subscribeUserOrder.setOrderId(order.getId());
        subscribeUserOrder.setSubscribeUserId(subscribeUser.getUserId());
        subscribeUserOrder.setReceiptTime(subscribeUser.getDeliveryStartTime().toString());
        subscribeUserOrder.setStatus(null);
        subscribeUserOrder.setAddTime(LocalDateTime.now());
        subscribeUserOrder.setUpdateTime(LocalDateTime.now());
        subscribeUserOrder.setDeleted(false);
        lumiereSubscribeUserOrderService.add(subscribeUserOrder);
        //创建订阅日志
        LumiereSubscribeUserLog log = new LumiereSubscribeUserLog();
        log.setUserId(subscribeOrder.getUserId());
        log.setUserName(subscribeUser.getUserName());
        log.setSubscribeUserId(subscribeOrder.getSubscribeId());
        log.setPrice(subscribeUser.getPrice());
        log.setAddTime(LocalDateTime.now());
        log.setPayType(4);
        log.setDeleted(false);
        LumiereSubscribe subscribe = lumiereSubscribeService.findById(subscribeUser.getSubscribeId());
        log.setSubscribeName(subscribe.getName());
        log.setBuyType(1);
        log.setBuyTime(subscribeUser.getStartTime());
        log.setExpireTime(subscribeUser.getEndTime());
        log.setStatus(2);
        lumiereSubscribeUserLogService.add(log);

        //给自己买卡
        String zcontent = "Congratulations, you got the " + subscribe.getName();
        noticeHelper.noticeUser( Constants.MSG_TYPE_OTHER,"Subscribe ", zcontent, order.getUserId(),subscribeUser);
        awsNotifyService.sendSms(MOBILE_CODE_ONE+user.getMobile(), zcontent,Constants.AWS_MESSAGE_TYPE_PROMOTIONAL);
        return ResponseUtil.ok("success");
    }


    /**
     * 创建或更新卡片 （赠送）
     *
     * @param userId          用户id
     * @param subscribeOrderId 订阅订单id
     */
    @Transactional
    public ResponseUtil.Response createOrUpdateIsGivee(Integer userId,Long subscribeOrderId,String message) {
        message=StrUtil.isNotEmpty(message)?message: LitemallWXConstants.WX_GIFTCARD_DEFAULT_MESSAGE;
        //更改支付状态
        LumiereSubscribeOrder subscribeOrder = lumiereSubscribeOrderService.getById(subscribeOrderId);
        if (ObjectUtil.isEmpty(subscribeOrder)) {
            return ResponseUtil.fail(PaymentResponseCode.ORDER_UNKNOWN, "订单不存在");
        }
        subscribeOrder.setPayStatus(2);
        lumiereSubscribeOrderService.updateById(subscribeOrder);

        LitemallUser user = litemallUserService.findById(subscribeOrder.getUserId());
        LitemallUser litemallGiveeUser = litemallUserService.queryMobileOrEmail(subscribeOrder.getAddUserName());

        //创建订阅用户
        LumiereSubscribeUser subscribeUser = new LumiereSubscribeUser();
        //通过ruleId查询订阅方式
        LumiereSubscribeRule rule = lumiereSubscribeRuleService.queryByPrimaryKey(subscribeOrder.getRuleId());
        subscribeUser.setSubscribeId(rule != null ? rule.getSubscribeId() : null);
        subscribeUser.setShopId(subscribeOrder.getShopId());
        subscribeUser.setGoodsId(subscribeOrder.getGoodsId());
        //设置goods_product_id
        subscribeUser.setGoodsProductId(queryGoodsProductId(subscribeOrder.getShopId(), subscribeOrder.getGoodsId()));
        subscribeUser.setNumber(subscribeOrder.getNumber());
        subscribeUser.setPrice(subscribeOrder.getPrice() != null ? subscribeOrder.getPrice() : rule.getPrice());
        subscribeUser.setAutoPayType((byte) 3);
        subscribeUser.setMethod(rule != null ? rule.getRuleType() : null);
        subscribeUser.setRuleId(subscribeOrder.getRuleId());

        subscribeUser.setDeliveryMethod(subscribeOrder.getDeliveryMethod() != null ? subscribeOrder.getDeliveryMethod() : null);
        //计算startTime和endTime
        LocalDateTime startTime = LocalDateTime.now();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar cal = Calendar.getInstance();
        Date startDate = Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant());
        cal.setTime(startDate);
        String end;
        LocalDateTime endTime = null;
        switch (rule.getRuleType()) {
            case 1:
                cal.add(Calendar.DATE, +7);
                end = sdf.format(cal.getTime());
                endTime = LocalDateTime.parse(end, df);
                break;

            case 2:
                cal.add(Calendar.MONTH, +1);
                end = sdf.format(cal.getTime());
                endTime = LocalDateTime.parse(end, df);
                break;

            default:
                cal.add(Calendar.YEAR, +1);
                end = sdf.format(cal.getTime());
                endTime = LocalDateTime.parse(end, df);
                break;
        }
        subscribeUser.setStartTime(startTime);
        subscribeUser.setEndTime(endTime);
        Object taxPrice = this.getTaxPrice(subscribeOrder);
        if (taxPrice instanceof ResponseUtil.Response) {
            ResponseUtil.Response resp = (ResponseUtil.Response) taxPrice;
            return ResponseUtil.fail(resp.getErrno(), resp.getErrmsg());
        } else {
            subscribeUser.setTaxPrice((BigDecimal) taxPrice);
        }

        if (subscribeOrder.getDeliveryStartTime() != null) {
            subscribeUser.setDeliveryStartTime(subscribeOrder.getDeliveryStartTime());
        }

        if (subscribeOrder.getDeliveryEndTime() != null) {
            subscribeUser.setDeliveryEndTime(subscribeOrder.getDeliveryEndTime());
        }


        //是赠送给别人，则改变订阅用户
        subscribeUser.setUserId(ObjectUtil.isNotEmpty(litemallGiveeUser) ? litemallGiveeUser.getId() : null);
        subscribeUser.setUserName(subscribeOrder.getAddUserName());

        subscribeUser.setAddTime(LocalDateTime.now());
        subscribeUser.setUpdateTime(LocalDateTime.now());
        subscribeUser.setPurchaserId(user.getId());
        lumiereSubscribeUserService.add(subscribeUser);
        //创建订单
        LitemallOrder order = new LitemallOrder();
        order.setUserId(userId);
        order.setShopId(subscribeOrder.getShopId());
        order.setOrderSn(RandomUtil.randomNumbers(16));
        order.setSerialNo(litemallOrderService.getTodayMaxSerialNo(subscribeOrder.getShopId()));
        order.setOrderStatus(null);
        order.setOrderPrice(subscribeOrder.getPrice());
        order.setEvaluationStatus((byte) 0);
        order.setMessage(subscribeOrder.getMessage());
        order.setGoodsPrice(order.getGoodsPrice());
        order.setPayType(Constants.PAY_TYPE_PAYPAL);
        order.setOrderSource((byte) 1);
        litemallOrderService.add(order);

        //创建订阅订单
        LumiereSubscribeUserOrder subscribeUserOrder = new LumiereSubscribeUserOrder();
        subscribeUserOrder.setOrderId(order.getId());
        subscribeUserOrder.setSubscribeUserId(subscribeUser.getUserId());
        subscribeUserOrder.setReceiptTime(subscribeUser.getDeliveryStartTime().toString());
        subscribeUserOrder.setStatus(null);
        subscribeUserOrder.setAddTime(LocalDateTime.now());
        subscribeUserOrder.setUpdateTime(LocalDateTime.now());
        subscribeUserOrder.setDeleted(false);
        lumiereSubscribeUserOrderService.add(subscribeUserOrder);
        //创建订阅日志
        LumiereSubscribeUserLog log = new LumiereSubscribeUserLog();
        log.setSubscribeUserId(subscribeOrder.getSubscribeId());
        log.setPrice(subscribeUser.getPrice());
        log.setAddTime(LocalDateTime.now());
        log.setPayType(4);
        log.setDeleted(false);
        LumiereSubscribe subscribe = lumiereSubscribeService.findById(subscribeUser.getSubscribeId());
        log.setSubscribeName(subscribe.getName());
        log.setBuyType(1);
        log.setBuyTime(subscribeUser.getStartTime());
        log.setExpireTime(subscribeUser.getEndTime());
        log.setStatus(2);

        if (ObjectUtil.isNotEmpty(litemallGiveeUser)) {
            /** 赠送给有账号的用户 */
            log.setUserId(litemallGiveeUser.getId());
            log.setUserName(litemallGiveeUser.getUsername());
            lumiereSubscribeUserLogService.add(log);
            SubscribeConfirmDTO subscribeConfirmDto =new SubscribeConfirmDTO();
            subscribeConfirmDto.setMessage(message);
            wxNewSubscribeManageService.sendNotificationToExistUser(subscribeConfirmDto,user,litemallGiveeUser,subscribeUser);
        } else {
            /** 赠送给没有账号的用户 */
            log.setUserId(null);
            log.setUserName(subscribeOrder.getAddUserName());
            lumiereSubscribeUserLogService.add(log);
            SubscribeConfirmDTO subscribeConfirmDto =new SubscribeConfirmDTO();
            subscribeConfirmDto.setMessage(message);
            subscribeConfirmDto.setGivee(subscribeOrder.getAddUserName());
            wxNewSubscribeManageService.sendNotificationToNotExistUser(subscribeConfirmDto,user,subscribeUser);
        }
        return ResponseUtil.ok("success");
    }

    /**
     * 查询货物产品id
     *
     * @param shopId  商店id
     * @param goodsId 商品id
     * @return {@link Integer}
     */
    public Integer queryGoodsProductId(Integer shopId, Integer goodsId) {
        List<LitemallGoodsProduct> p = litemallGoodsProductService.queryByGidAndSid(goodsId, shopId);
        if (p.size() > 0) {
            return p.get(0).getId();
        } else {
            p = litemallGoodsProductService.queryByGidAndSid(goodsId, null);
            if(p.size() > 0){
                return  p.get(0).getId();
            }
            return null;
        }
    }

    /**
     * 得到税收价格
     *
     * @param subscribeOrder subscribeOrder
     * @return {@link Object}
     */
    public Object getTaxPrice(LumiereSubscribeOrder subscribeOrder) {
        //查询税费价格
        Integer cityRegionId = getShopRegionId(subscribeOrder.getShopId());
        //goods对应的shopId
        LitemallGoods goods = litemallGoodsService.findById(subscribeOrder.getGoodsId());
        Integer shopId = goods != null ? goods.getShopId() : null;
        LitemallGoodsRegion goodRegion = goodsRegionService.findByGidAndCityId(subscribeOrder.getGoodsId(), cityRegionId);
        //总店的商品shopId为空，无法找到对应的cityRegionId,无法算税
        BigDecimal taxPrice = BigDecimal.ZERO;
        if (null == goodRegion) {
            if (shopId != null) {
//                 return ResponseUtil.fail(GOODS_SHOP_INVALID, "商品不属于该店铺区域");
            } else {
                return new BigDecimal(0);
            }
        } else {
            Integer[] taxTypes = goodRegion.getTaxTypes();
            if (taxTypes.length != 0) {
//            return ResponseUtil.fail(GOODS_SHOP_REGION_TAX_NOTSET, "商品在该店铺区域未设置税费类型");
                for (int j = 0; j < taxTypes.length; j++) {
                    Integer taxType = taxTypes[j];
                    LitemallTax litemallTax = litemallTaxService.findById(taxType);
                    if (null == litemallTax) {
                        return ResponseUtil.fail(TAX_NOT_EXIST, "商品在该店铺区域设置的税费类型不存在");
                    } else if (litemallTax.getDeleted() || (!litemallTax.getEnable())) {
                        continue;
                    }

                    BigDecimal value = litemallTax.getValue();
                    BigDecimal price = subscribeOrder.getPrice().multiply(value).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
                    taxPrice = taxPrice.add(price);
                }
            }
        }
        return taxPrice;
    }
    /**
     * 得到车间区域id
     *
     * @param shopId 商店id
     * @return {@link Integer}
     */
    private Integer getShopRegionId(Integer shopId) {
        List<LitemallShopRegion> litemallShopRegions = litemallShopRegionService.queryByShopId(shopId);
        if (!CollectionUtils.isEmpty(litemallShopRegions)) {
            for (LitemallShopRegion litemallShopRegion : litemallShopRegions) {
                LitemallRegion litemallRegion = regionService.findById(litemallShopRegion.getRegionId());
                if (Constants.REGION_TYPE_CITY == litemallRegion.getType()) {
                    return litemallShopRegion.getRegionId();
                }
            }
        }
        return null;
    }


}
